package com.jwaoo.bluetooth;

import android.annotation.TargetApi;
import android.bluetooth.BluetoothDevice;
import android.content.Context;
import android.os.Build;
import android.util.Log;
import com.cavan.android.CavanAndroid;
import com.jwaoo.android.JwaooBleToy;
import com.jwaoo.android.JwaooBleToy.JwaooBleToyEventListener;
import com.jwaoo.android.JwaooBleToy.JwaooToyBatteryInfo;
import com.jwaoo.android.JwaooBleToy.JwaooToyMotoMode;
import com.jwaoo.android.JwaooToySensor;
/*
* 手环,飞机杯:
*  Bluetooth *ins = Bluetooth.getInstance(context);
*  ins.connect(macaddr);
*  if (ins.getConnectedDeviceName()== SenseBand or SenseTube
*      ins.enableSensorDataTranfer(true);
*  every sec do :
*      freq = ins.getMotionFreq();
*      webrct.senddata(freq);
* */

/*
* 震动棒:
*  Bluetooth *ins = Bluetooth.getInstance(context);
*  ins.connect(macaddr);
*  if (ins.getConnectedDeviceName()== SenseVibe warm
*      freq = webrct.recvdata();
*      vibeMotoSpeed = ins.getMotoWorkSpeedLevel(freq)
*      ins.setMotoWorkSpeed(vibeMotoSpeed);
*
* */

@SuppressWarnings("static-access")
@TargetApi(Build.VERSION_CODES.JELLY_BEAN_MR2)
public class Bluetooth {

	private static final String TAG = Bluetooth.class.getSimpleName();
    //蓝牙按键

    public static final int BT_KEY_ADD = 0;

    public static final int BT_KEY_O = 1;

    public static final int BT_KEY_SUB = 2;

    public static final int BT_KEY_MAX = 3;

    public static final int BT_ACTION_LONG = 0;

    public static final int BT_ACTION_ONE = 1;

    public static final int BT_ACTION_TWO = 2;

    public static final int BT_ACTION_THREE = 3;

    /*两个马达同时震动，锯齿波，相位振幅一样*/
    public static final int MOTO_MODE_01 = 1;
    /*主马达，锯齿波*/
	public static final int MOTO_MODE_02 = 2;
	/*辅助马达，锯齿波*/
	public static final int MOTO_MODE_03 = 3;
	/*两个马达同时震动，锯齿波，相位相反，振幅一样,频率较慢*/
	public static final int MOTO_MODE_04 = 4;
	/*两个马达同时震动，锯齿波，相位相反，振幅一样,频率较快*/
	public static final int MOTO_MODE_05 = 5;
	/*两个马达同时震动，方波，相位相反，振幅一样*/
	public static final int MOTO_MODE_06 = 6;
	/*两个马达同时震动，方波，相位相反，振幅一样*/
	public static final int MOTO_MODE_07 = 7;
	/*两个马达同时震动，锯齿波，相位相反，振幅一样,频率变化*/
	public static final int MOTO_MODE_08 = 8;

	public static final int MOTO_MAX_SPEED = 18;
	public static final int MOTO_MIN_SPEED = 6;

    private  int _MOTE_MODE   = JwaooBleToy.MOTO_MODE_SAWTOOTH;

    public static final int BT_ERROR_UNSUPPORTED = -1;
    public static final int BT_ERROR_NOTCONNECTED = -1;

	private static final int SENSOR_DELAY = 20;
	private JwaooBleToy mBleToy;

	//private Context mContext;
	private BluetoothDevice mDevice;

	// 蓝牙连接状态事件
	private BTEvent onBTEvent;

	// 蓝牙数据
	private BTDataMsg onBTDataMsg;

	// 是否上报数据
	private boolean isEventEnable = false;

	private static final float NoFilterSpeed = 0.45f;

	private static final float FilterSpeed = 0.7f;

	private BTTubeDataProcess btDataProc;
	private BTBandDataProcess mBandDataProc;
	private MotionProcess mProcess;
	private float smoothSpeed = NoFilterSpeed;

	private int btLevel = 0;

	private boolean isFilter = false;

	private static Bluetooth instance = null;
	private OptionCallback optionCallback;

	private int moteLevel = 6;
	/*
	* 获取单例类
	* */
	static public synchronized Bluetooth getInstance(Context context){
        if (instance == null){
            instance = new Bluetooth(context);
        }
        return instance;
    }

	private Bluetooth(Context context) {
		//this.mContext = context;

		mBleToy =  JwaooBleToy.getInstance(context);
        //JwaooBleToy.MOD
		mBleToy.setEventListener(jwaooBleToyEventListener);
	}

	public void setOptionCallback(OptionCallback callback){
		optionCallback = callback;
	}

	// 连接蓝牙
	public void connect(String macAddr) {

		CavanAndroid.DLOG_ENABLE = true;
		CavanAndroid.ELOG_ENABLE = true;
		CavanAndroid.WLOG_ENABLE = true;
		CavanAndroid.PLOG_ENABLE = true;

		if (mBleToy != null) {

			Log.w("Bluetooth","disconnected", new Throwable());
			mBleToy.disconnect();

		}

		if (macAddr != null && !macAddr.isEmpty()) {
			mDevice = mBleToy.getRemoteDevice(macAddr);
		}
		if (mDevice == null) {
			Log.d(TAG, "mDevice == null...");
			return;
		} else {
			Log.d(TAG, "mDevice address : " + mDevice.getAddress());

			mBleToy.connect(mDevice);
		}

	}

	// 是否上报数据
	public synchronized void enableSensorDataTranfer(boolean enable) {
		onBTDataMsg = null;

//		if (mBleToy != null && mBleToy.isConnected()) {
//			try {
//				mBleToy.setSensorEnable(isEventEnable, SENSOR_DELAY);
////				isEventEnable = false;
//			} catch (Exception e) {
//				e.printStackTrace();
//			}
//		}else{
//			isEventEnable = enable;
//		}
		isEventEnable = enable;
	}

    /*
    * 获取连接设备的名称，SenseTube,SenseBand,SenseVibe warm
    * */
	public String getConnectedDeviceName(){
	    if (mBleToy != null && mBleToy.isConnected()){
	        return mBleToy.getDeviceName();
        }
        return null;
    }
	/**
	 * 是否连接上
	 * 
	 * @return
	 */
	public boolean isConnected() {

		if (mBleToy != null) {

			return mBleToy.isConnected();
		}

		return false;

	}


	/**
	 * 断开连接
	 */
	public void disconnect() {
		if (mBleToy != null) {
			Log.w("Bluetooth","disconnected", new Throwable());
			mBleToy.disconnect();

		}

	}
    /*
    * 通过手环或飞机杯的动作获取获取相应马达速度
    * */
    private void adjust(int max){
		if (moteLevel > max){
			moteLevel--;
		}else if (moteLevel < max){
			moteLevel++;
		}
		if (moteLevel > 0 && moteLevel < 6 && max == 0){
			moteLevel = 0;
		}
	}
	private int getMotoWorkSpeedLevel(int freq){
        if (freq == 0){
			adjust(0);
        }else{
            if (freq <= 6){
				adjust(18);
            }else if (freq <= 9){
				adjust(16);
            }else if (freq <= 12){
				adjust(14);
            }else if (freq <= 15){
				adjust(12);
            }else if (freq <= 18){
				adjust(10);
            }else if (freq <= 21){
				adjust(8);
            }else{
				adjust(6);
            }
        }
		return moteLevel;
    }

	/*
	* 获取飞机杯或手环的运动频率,数越小越快，0表示停止运动
	* */
    public int getMotionFreq(){
        if (mProcess != null)
            return mProcess.frequency();

        return 0;
    }

    /*
    * 设置马达的震动方式
    * */
    public void setMotorWorkMode(int mode){
    	switch(mode){
			case MOTO_MODE_01:
				_MOTE_MODE = JwaooBleToy.MOTO_MODE_SAWTOOTH;
				break;
			case MOTO_MODE_02:
				_MOTE_MODE = JwaooBleToy.MOTO_MODE_LINE_MAIN;
				break;
			case MOTO_MODE_03:
				_MOTE_MODE = JwaooBleToy.MOTO_MODE_LINE_AUX;
				break;
			case MOTO_MODE_04:
				_MOTE_MODE = JwaooBleToy.MOTO_MODE_SAWTOOTH;
				break;
			case MOTO_MODE_05:
				_MOTE_MODE = JwaooBleToy.MOTO_MODE_SAWTOOTH_FAST;
				break;
			case MOTO_MODE_06:
				_MOTE_MODE = JwaooBleToy.MOTO_MODE_SQUARE;
				break;
			case MOTO_MODE_07:
				_MOTE_MODE = JwaooBleToy.MOTO_MODE_SQUARE_FAST;
				break;
			case MOTO_MODE_08:
				_MOTE_MODE = JwaooBleToy.MOTO_MODE_SAWTOOTH;
				break;
			default:
				break;

		}
		if (mBleToy != null && mBleToy.isConnected()) {
			try {
				mBleToy.setMotoMode(_MOTE_MODE, moteLevel);
			} catch (Exception e) {
				e.printStackTrace();
			}
		}
	}
    /*
    * 获取电池的电量
    * */
    public int getBatteryLevel(){
        if (mBleToy != null && mBleToy.isConnected()) {
            JwaooToyBatteryInfo info;
            try {
                info = mBleToy.getBatteryInfo();
                Log.d(TAG, "info :" + info);
                if (info != null)
                    return info.getLevel();
            } catch (Exception e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }
        return -1;
    }

    /*
    * 通过接收到的band或者tube的运动速度设置马达的震动强度
    * */
    public void setMotorWorkSpeedByFreq(int freq){
		int level = getMotoWorkSpeedLevel(freq);
		setMotorWorkSpeed(level);
    }

	/*
	* 设置马达的震动强度
	* */
	public void setMotorWorkSpeed(int level){
		try {
			int mode = _MOTE_MODE;
			if (level <= 0){
				mode = JwaooBleToy.MOTO_MODE_IDLE;
				level = 0;
			}
			if (mBleToy != null && mBleToy.isConnected())
				mBleToy.setMotoMode(mode, level);
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
    /*
    * 蓝牙连接状态的回调
    * */
    public interface BTEvent {
        public void onConnected(boolean isConnected);
    }

    public void setBtCallBack(BTEvent onBTEvent) {

        this.onBTEvent = onBTEvent;
    }

	/**
	 * 注册的蓝牙监听广播
	 */
	public void registerBT(){
		
		if (mBleToy != null) {
			mBleToy.registerBroadcastReceiver();
		}
		
	}
	
	/**
	 * 取消蓝牙监听广播
	 */
	public void unregisterBT(){
		if(mBleToy != null){
			mBleToy.unregisterBroadcastReceiver();
		}
	}


	/**
	 * 获取电池信息
	 * 
	 * @return
	 */
	public JwaooToyBatteryInfo getBatteryInfo(String macAddr) {
		if (mBleToy != null) {
			JwaooToyBatteryInfo info;
			try {
				info = mBleToy.getBatteryInfo();
				Log.d(TAG, "info :" + info);
				return info;
			} catch (Exception e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			} 
		}
		return null;
	}

	public interface BTDataMsg {

		public void onDataReceive(float depth, float freq, float smoothFactor);

		public void onKeyStateChanged(int code, int state);
	}

	public JwaooToyBatteryInfo getBatteryInfo() {
		try {
			return mBleToy.getBatteryInfo();
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		return null;

	}

	JwaooBleToyEventListener jwaooBleToyEventListener = new JwaooBleToyEventListener() {

		@Override
		public boolean onInitialize() {
			// setFreqFuzz(10);
			// setDepthFuzz(50);

			try {
				if (!mBleToy.setLongClickEnable(true))
					return false;
				if (!mBleToy.setMultiClickEnable(true))
					return false;

				btLevel = 0;

				isFilter = false;

				Log.d(TAG, "onInitialize...");

				if (mBleToy.getDeviveId() == JwaooBleToy.DEVICE_ID_MODEL06) {
					if (!mBleToy.setMotoEventEnable(true)) {
						return false;
					}

					JwaooToyMotoMode mode = mBleToy.getMotoMode();
					if (mode == null) {
						return false;
					}
					btLevel = mode.getLevel();

				}
                mBleToy.setSensorEnable(true, SENSOR_DELAY);
			} catch (Exception e) {
				e.printStackTrace();
				return false;
			}

			Log.e(TAG, "btLevel = " + btLevel);

			isFilter = btLevel != 0;
			smoothSpeed = isFilter ? FilterSpeed : NoFilterSpeed;
			btDataProc = new BTTubeDataProcess();
			mBandDataProc = new BTBandDataProcess();
			mProcess = new MotionProcess();
			return true;
		}

		@Override
		public void onBluetoothAdapterStateChanged(boolean enabled) {
			if (enabled) {
				//VRApplication.getInstance().tryConnectBT();

			}
		}

		@Override
		public void onConnectFailed() {
			// TODO Auto-generated method stub
			Log.d(TAG, "onConnectFailed...");
			// 尝试连接
			if (mBleToy.isPoweredOn()) {

			}
			if (onBTEvent != null)
				onBTEvent.onConnected(false);

		}

		@Override
		public void onConnectionStateChanged(boolean connected) {
			CavanAndroid.eLog("onConnectionStateChange: connected = "
					+ connected);
			optionCallback.onConnectionStateChanged(connected);
			synchronized (Bluetooth.this) {

//				if (connected) {
//
//					if (isEventEnable) {
//						try {
//							mBleToy.setSensorEnable(isEventEnable, SENSOR_DELAY);
//							isEventEnable = false;
//						} catch (Exception e) {
//							// TODO Auto-generated catch block
//							e.printStackTrace();
//						}
//					}
//				}

				if (onBTEvent != null) {

					onBTEvent.onConnected(connected);

				}

			}

		}

		@Override
		public void onMotoStateChanged(int mode, int level) {

			btLevel = level;

			isFilter = btLevel != 0;

			smoothSpeed = isFilter ? FilterSpeed : NoFilterSpeed;

			Log.e(TAG, "btLevel = " + btLevel);

		}

		@Override
		public void onSensorDataReceived(JwaooToySensor sensor, byte[] data) {


//			if (isEventEnable) {

				double xAcel = -mBleToy.getSensor().getAxisX();
				double yAcel = mBleToy.getSensor().getAxisY();
				double zAcel = mBleToy.getSensor().getAxisZ();

				boolean isBand = mBleToy.getDeviveId() == JwaooBleToy.DEVICE_ID_MODEL10;

				double[] btData = null;

				if (isBand) {// 手环

					btData = mBandDataProc.getCurDepth(xAcel, isFilter);

				} else {// 飞机杯

					btData = btDataProc.getCurDepth(xAcel, isFilter);
				}
				mProcess.process((float)btData[0]);

//				Log.e(TAG,
//						"AccData  "+(float)xAcel+" ,"+(float)yAcel+" ,"+(float)zAcel+",");
//				Log.e(TAG,"xAcel = "+xAcel + "btData = " + btData[0]);
//			}

		}

		@Override
		public void onKeyClicked(int code, int count) {
			Log.d(TAG, "onKeyClicked keycode=" + code + " count = " + count);

			if (isEventEnable) {

				if (mBleToy.getDeviveId() == JwaooBleToy.DEVICE_ID_MODEL10) {

					if (count == BT_ACTION_ONE) {

						code = BT_KEY_MAX;

					} else if (count == BT_ACTION_TWO) {

						code = BT_KEY_O;

						count = BT_ACTION_ONE;

					} else if (count == BT_ACTION_THREE) {

						code = BT_KEY_O;

						count = BT_ACTION_LONG;
					}

				}

			}

		}

		@Override
		public void onKeyLongClicked(int code) {

			Log.d(TAG, "onKeyLongClicked keycode=" + code);

			if (isEventEnable) {

				if (mBleToy.getDeviveId() == JwaooBleToy.DEVICE_ID_MODEL10) {

					code = BT_KEY_MAX;
				}

			}

		}

		@Override
		public void onDebugDataReceived(byte[] arg0) {
			// TODO Auto-generated method stub

		}

		@Override
		public void onKeyStateChanged(int arg0, int arg1) {
			// TODO Auto-generated method stub

		}

		@Override
		public void onUpgradeComplete(boolean arg0) {
			// TODO Auto-generated method stub

		}

		@Override
		public void onBatteryStateChanged(
				JwaooToyBatteryInfo jwaootoybatteryinfo) {
			// TODO Auto-generated method stub
			
		}
	};

	public interface OptionCallback{
		void onConnectionStateChanged(boolean connected);
	}
}
